/*
** Copyright (C) 2010 Calin Radoni
**
** This file is part of CHScanner.
**
** CHScanner is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** CHScanner is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with CHScanner. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "ScanMessages.h"

#include "WorkCfg.h"
#include "WorkDefinitions.h"

#include "ListOfAddresses.h"
#include "ListOfPorts.h"

#include "MWinPcap.h"

#include "MMachineInfoList.h"

#include "PacketBuilderEx.h"
#include "PacketBuilderEx6.h"
#include "PacketBuilderPromisc.h"

#include "ScanMethodArp.h"
#include "ScanMethodPing.h"
#include "ScanMethodSyn.h"
#include "ScanMethodDns.h"
#include "ScanMethodAck.h"
#include "ScanMethodFNX.h"
#include "ScanMethodUdp.h"
#include "ScanMethodIpProto.h"
#include "ScanMethodNetBios.h"
#include "ScanMethodWOL.h"
#include "ScanMethodSnmp.h"
#include "ScanMethodDHCP.h"
#include "ScanMethodPromisc.h"
#include "ScanMethod4PingBcast.h"

#include "ScanMethod6PingBcast.h"
#include "ScanMethod6ND.h"
#include "ScanMethod6MLD.h"
#include "ScanMethod6Ping.h"
#include "ScanMethod6Syn.h"
#include "ScanMethod6Ack.h"
#include "ScanMethod6FNX.h"
#include "ScanMethod6Udp.h"
#include "ScanMethod6Proto.h"

#include "ScanMethodWMI.h"
#include "ScanMethodIgmp.h"
#include "ScanMethodShutdown.h"

#include "ScanMethodHunt.h"

#include "ScanMethodPassive.h"

#include "MWMIWorker.h"

#include "MArpCacheList.h"

#include "MConfig.h"

#include "MIPLocator.h"

class TheScanner
{
private:
	bool                 isRunning;
	bool                 stopStopStop;
	MWinPcap             winPcap;
	PacketBuilderEx      packetBuilderEx;
	PacketBuilderEx6     packetBuilderEx6;
	PacketBuilderPromisc packetBuilderPromisc;
	HANDLE               eventDone;

	WorkCfg              config;

	ListOfAddresses      listAddrs;
	ListOfPorts          listPorts;

	DWORD ComputeDeltaTime(DWORD, DWORD);

	DWORD scanStartTime;
	int   RefreshAndExit(UINT, int);

	void FillDnsServerMAC(BYTE*);

	MWMIWorker           wmiWorker;

	ScanMethodArp        scanMethodArp;
	ScanMethodPing       scanMethodPing;
	ScanMethodDns        scanMethodDns;
	ScanMethodSyn        scanMethodSyn;
	ScanMethodAck        scanMethodAck;
	ScanMethodFNX        scanMethodFin;
	ScanMethodFNX        scanMethodNull;
	ScanMethodFNX        scanMethodXmas;
	ScanMethodUdp        scanMethodUdp;
	ScanMethodIpProto    scanMethodIpProto;
	ScanMethodNetBios    scanMethodNetBios;
	ScanMethodWOL        scanMethodWOL;
	ScanMethodSnmp       scanMethodSnmp;
	ScanMethodDHCP       scanMethodDHCP;
	ScanMethodPromisc    scanMethodPromisc;
	ScanMethod4PingBcast scanMethod4PingBcast;

	ScanMethod6PingBcast scanMethod6PingBcast;
	ScanMethod6ND        scanMethod6ND;
	ScanMethod6MLD       scanMethod6MLD;
	ScanMethod6Ping      scanMethod6Ping;
	ScanMethod6Syn       scanMethod6Syn;
	ScanMethod6Ack       scanMethod6Ack;
	ScanMethod6FNX       scanMethod6Fin;
	ScanMethod6FNX       scanMethod6Null;
	ScanMethod6FNX       scanMethod6Xmas;
	ScanMethod6Udp       scanMethod6Udp;
	ScanMethod6Proto     scanMethod6Proto;

	ScanMethodWMI        scanMethodWMI;
	ScanMethodIgmp       scanMethodIgmp;
	ScanMethodShutdown   scanMethodShutdown;

	ScanMethodHunt       scanMethodHunt;

	ScanMethodPassive    scanMethodPassive;

	// Return one of the MSR_* messages
	int  StartScanningMethod(MWinPcap*, WorkCfg*, HANDLE, WorkMethodType, CString, ListOfAddresses*, MMachineInfoList*, WorkPhaseType, HWND);

	// return one of the MSR_* messages
	int   StartScanPhase(WorkPhaseType);

	int   ScanPhaseWrapper(WorkPhaseType);

	void  SendStatusMessage(UINT, WPARAM, LPARAM);
	void  PostStatusMessage(UINT, WPARAM, LPARAM);

	int RebuildAddrListByMAC(void);
	void CleanUpAliveFlag(void);
	int RebuildAddrListByAlive(void);

	// return one of the MSR_* messages
	int  Initialize(WorkCfg*);

	void StartScanPassiveMode(void);

	void StartScanHuntMode(void);

	// return one of the MSR_* messages
	int  StartScan(void);

	void StopScan(void);

	friend UINT MainScanner_StartScan(void* param);

	MMachineInfoList machineList;
	int PopulateMachineList(void);

	__time64_t startTime;
	void MemorizeStartTime(void);

	bool systemArpCacheUpdated;
	void UpdateSystemArpCache(WorkPhaseType, WorkMethodType);

	MArpCacheList arpCacheList;
	void UpdateArpCache(void);

	int abortReason;

	TCHAR userName[CREDUI_MAX_USERNAME_LENGTH + 1];
	TCHAR userPass[CREDUI_MAX_PASSWORD_LENGTH + 1];
	SEC_WINNT_AUTH_IDENTITY authIdentity;
	bool GetUserCredentials(void);
	bool GetProcessCredentials(void);
	void CleanUpUserCredentials(void);

public:
	TheScanner(void);
	~TheScanner(void);

	HWND msgWnd;
	CString applicationPath;
	CString defaultInterfaceName;
	MConfig* appCfg;

	int  Start(WorkCfg*);
	void Stop(void);
	bool IsRunning(void);

	int GetMachInfoCount(void);
	MMachineInfo* GetMachInfo(int);
	MMachineInfoList* GetMachInfoList(void);

	CString GetStartTime(void);
	CString GetNameFromTime(void);

	CString GetLocalIPv4AddressAsString(void);
	CString GetLocalIPv6AddressAsString(void);

	// call this AFTER GetLocalIPAddressAsString !!!
	CString GetInterfaceName(void);
	// call this AFTER GetLocalIPAddressAsString !!!
	CString GetIpInterfaceAdapterName(void);
	// call this AFTER GetLocalIPAddressAsString !!!
	int     GetIpInterfaceCount(void);
	// call this AFTER GetLocalIPAddressAsString !!!
	MIpInterfaceInfo* GetIpInterfaceInfo(int);

	// call this AFTER GetLocalIPAddressAsString !!!
	DWORD GetLocalIP(void);
	// call this AFTER GetLocalIPAddressAsString !!!
	DWORD GetLocalIPMask(void);

	MWinPcap* GetWinPcap(void);

	MArpCacheList* GetArpCacheList(void);

	bool automaticMode;

	ScanMethodHuntParams xHuntParams;
};
